package com.example.demo.util;


import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT token 工具类,提供JWT生成,校验,工作
 */
@Component
public class JwtUtil {
    private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);
    /**
     * 秘钥
     */
    private static final String SECRET ="my_secret";
    /**
     * 过期时间,单位为天
     */
    private static final int EXPIRE =200000;

    private String header;

    /**
     * 创建短时间token
     * @return token
     */
    //.withExpiresAt(expireDate)//过期时间
    public static String createToken(String uuid) {
        Date nowDay=new Date(System.currentTimeMillis());
        Date expireDate = DateUtil.offset(nowDay, DateField.DAY_OF_MONTH, EXPIRE);
        System.out.println("expireDate = " + expireDate);
        Map<String, Object> map = new HashMap<>();
        //设置加密算法声明
        map.put("alg", "HS256");
        //设置声明类型，这里是jwt
        map.put("typ", "JWT") ;
        String token= JWT.create()
                .withExpiresAt(expireDate)
                .withHeader(map)
                .withClaim("uuid", uuid)//携带数据
                .withIssuedAt(new Date())
                .sign(Algorithm.HMAC256(SECRET));//加密
        JWTVerifier verification = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT verify = verification.verify(token);
        System.out.println("jwt.getExpiresAt() = " + verify.getExpiresAt());
        return token;
    }
    /**
     * 创建刷新token
     * @return token
     */
    //.withExpiresAt(expireDate)//过期时间
    public static String createRefreshToken(String uuid) {
        //过期时间为7天
        Date nowDay=new Date(System.currentTimeMillis());
        Date expireDate = DateUtil.offset(nowDay, DateField.DAY_OF_MONTH, EXPIRE);
        Map<String, Object> map = new HashMap<>();
        //设置加密算法声明
        map.put("alg", "HS256");
        //设置声明类型，这里是jwt
        map.put("typ", "JWT") ;
        String token= JWT.create()
                .withExpiresAt(expireDate)
                .withHeader(map)
                .withClaim("uuid", uuid)//携带数据
                .withIssuedAt(new Date())
                .sign(Algorithm.HMAC256(SECRET));//加密

        return token;
    }
    /**
     * 验证token
     * @param token,并返回jwt实体
     * @return  uuid
     */
    public static String verifyToken(String token){
        DecodedJWT jwt=null;
        String uuid = null;
        try {
            JWTVerifier verification = JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwt = verification.verify(token);
            System.out.println("jwt.getExpiresAt() = " + jwt.getExpiresAt());
            Map<String, Claim> claims = jwt.getClaims();
             uuid = claims.get("uuid").asString();

        } catch (IllegalArgumentException | JWTVerificationException e ) {
            e.printStackTrace();
            logger.error(e.getMessage(), "解析编码异常");
            throw  new  IllegalArgumentException();

        }
        return uuid;
    }
    /**
     *
     * 校验token是否过期
     * @param token
     * @return
     */
    public static boolean isTokenExpired(String token){
        DecodedJWT jwt=null;
        Date expiresAt=null;
        try {
            JWTVerifier verification = JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwt = verification.verify(token);
            expiresAt = jwt.getExpiresAt();

        } catch (IllegalArgumentException | JWTVerificationException e) {
            e.printStackTrace();
            logger.error(e.getMessage(), "解析编码异常");
        }

        return expiresAt.before(new Date());
    }

}
